<template>
  <!-- 模板部分：定义一个容器元素用于渲染太阳系3D场景 -->
  <div ref="container" class="solar-system-container"></div>
</template>

<script setup lang="ts">
// 导入Vue 3的Composition API相关函数
// ref: 创建响应式引用
// onMounted: 组件挂载生命周期钩子
// onUnmounted: 组件卸载生命周期钩子
import { ref, onMounted, onUnmounted } from 'vue';
// 导入Three.js库，用于创建3D图形
import * as THREE from 'three';

// 创建一个响应式引用，用于存储DOM容器元素
// ref<HTMLElement | null>(null) 表示这个引用可以是HTMLElement类型或者null
const container = ref<HTMLElement | null>(null);

// Three.js相关变量声明
let scene: THREE.Scene;           // 3D场景，包含所有要渲染的天体对象
let camera: THREE.PerspectiveCamera; // 透视相机，决定如何将3D场景投影到2D屏幕
let renderer: THREE.WebGLRenderer; // WebGL渲染器，负责将3D场景渲染到canvas中
let sun: THREE.Mesh;              // 太阳网格对象
let earth: THREE.Mesh;            // 地球网格对象
let moon: THREE.Mesh;             // 月球网格对象
let earthOrbit: THREE.Mesh;       // 地球轨道可视化网格
let moonOrbit: THREE.Mesh;        // 月球轨道可视化网格
let animationId: number;          // 动画ID，用于控制动画循环

// 初始化Three.js场景的函数
const initThreeJS = (): void => {
  // 检查容器元素是否存在，如果不存在则退出函数
  if (!container.value) {return;}

  // 初始化Three.js场景
  // 创建3D场景
  // THREE.Scene() - 创建一个新的3D场景对象
  // 作用：场景是所有3D对象的容器，用于管理要渲染的所有天体、灯光、相机等
  // 参数：无
  // 返回值：THREE.Scene实例
  scene = new THREE.Scene();
  
  // 创建透视相机
  // 创建透视相机
  // THREE.PerspectiveCamera() - 创建透视投影相机
  // 作用：模拟人眼视角，近大远小，用于3D场景渲染
  // 参数：
  //   - fov (number): 视野角度，单位度，默认50，这里75度
  //   - aspect (number): 宽高比，窗口宽度除以高度
  //   - near (number): 近裁剪面，距离相机多近开始渲染，默认0.1
  //   - far (number): 远裁剪面，距离相机多远停止渲染，默认1000
  // 返回值：THREE.PerspectiveCamera实例
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  
  // 创建WebGL渲染器
  // THREE.WebGLRenderer() - 创建WebGL渲染器对象
  // 作用：使用WebGL技术在canvas上渲染3D场景
  // 参数：
  //   - options (object): 配置选项
  //     - antialias (boolean): 是否开启抗锯齿，true使边缘更平滑
  //   - 其他可选参数：alpha, precision, depth, stencil等
  // 返回值：THREE.WebGLRenderer实例
  renderer = new THREE.WebGLRenderer({ antialias: true });

  // 设置渲染器大小
  // renderer.setSize() - 设置渲染器的输出canvas大小
  // 作用：调整渲染器绘制区域的大小，匹配窗口尺寸
  // 参数：
  //   - width (number): 宽度像素值，这里使用窗口内宽
  //   - height (number): 高度像素值，这里使用窗口内高
  //   - updateStyle (boolean, 可选): 是否更新canvas样式，默认true
  // 返回值：无
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 设置像素比率
  // renderer.setPixelRatio() - 设置设备像素比率
  // 作用：适配高DPI屏幕，防止渲染模糊，提高显示质量
  // 参数：
  //   - ratio (number): 像素比率，通常使用window.devicePixelRatio
  // 返回值：无
  renderer.setPixelRatio(window.devicePixelRatio);
  // 将渲染器canvas添加到DOM
  // container.value.appendChild() - DOM操作方法
  // 作用：将Three.js渲染器的canvas元素添加到页面中显示
  // 参数：
  //   - renderer.domElement: 渲染器的canvas DOM元素
  // 返回值：无
  container.value.appendChild(renderer.domElement);

  // 添加环境光 - 提供均匀的基础照明，模拟太空中的微弱环境光
  // 创建环境光
  // THREE.AmbientLight() - 创建环境光光源
  // 作用：提供均匀的全方向照明，没有阴影，模拟太空中的微弱环境光
  // 参数：
  //   - color (number/string): 光的颜色，十六进制值(0x333333)或CSS颜色字符串
  //   - intensity (number, 可选): 光强度，默认1.0
  // 返回值：THREE.AmbientLight实例
  const ambientLight = new THREE.AmbientLight(0x333333);
  // 将光源添加到场景
  // scene.add() - 将对象添加到场景中
  // 作用：将创建的环境光源添加到场景中进行渲染和光照计算
  // 参数：
  //   - object (Object3D): 要添加的对象，这里为环境光
  // 返回值：无
  scene.add(ambientLight);

  // 添加点光源用于太阳 - 点光源从一点向所有方向发射光线
  // 创建点光源
  // THREE.PointLight() - 创建点光源
  // 作用：从一点向所有方向发射光线，模拟太阳光，会产生衰减
  // 参数：
  //   - color (number/string): 光的颜色，十六进制值(0xffffff)或CSS颜色字符串
  //   - intensity (number, 可选): 光强度，默认1.0，这里1.5
  //   - distance (number, 可选): 衰减距离，光线传播的最大距离，默认0（无衰减），这里100
  //   - decay (number, 可选): 衰减系数，默认2
  // 返回值：THREE.PointLight实例
  const sunLight = new THREE.PointLight(0xffffff, 1.5, 100);
  // 设置光源位置
  // sunLight.position.set() - 设置光源在3D空间中的位置
  // 作用：确定点光源的来源位置，这里与太阳中心重合
  // 参数：
  //   - x (number): X轴坐标，0表示场景中心
  //   - y (number): Y轴坐标，0表示场景中心
  //   - z (number): Z轴坐标，0表示场景中心
  // 返回值：无
  sunLight.position.set(0, 0, 0);
  // 将点光源添加到场景
  // scene.add() - 将对象添加到场景中
  // 作用：将创建的点光源添加到场景中进行渲染和光照计算
  // 参数：
  //   - object (Object3D): 要添加的对象，这里为点光源
  // 返回值：无
  scene.add(sunLight);

  // 创建太阳
  // 太阳几何体：使用球体几何体，参数：半径(2), 宽度分段数(32), 高度分段数(32)
  // 创建球体几何体
  // THREE.SphereGeometry() - 创建球体几何体
  // 作用：定义太阳的3D形状，包含顶点、面、UV坐标等几何信息
  // 参数：
  //   - radius (number): 球体半径，单位为单位长度，这里2
  //   - widthSegments (number): 宽度分段数，32表示球体较平滑
  //   - heightSegments (number): 高度分段数，32表示球体较平滑
  //   - phiStart (number, 可选): 起始经度角，默认0
  //   - phiLength (number, 可选): 经度角范围，默认2π
  //   - thetaStart (number, 可选): 起始纬度角，默认0
  //   - thetaLength (number, 可选): 纬度角范围，默认π
  // 返回值：THREE.SphereGeometry实例
  const sunGeometry = new THREE.SphereGeometry(2, 32, 32);
  // 创建标准材质
  // THREE.MeshStandardMaterial() - 创建基于物理渲染的标准材质
  // 作用：定义太阳表面的外观特性，支持自发光效果，模拟太阳发光
  // 参数：
  //   - options (object): 材质配置选项
  //     - color (number): 基础颜色，十六进制值(0xff9900)表示橙黄色
  //     - emissive (number): 自发光颜色，十六进制值(0xff5500)表示橙红色
  //     - emissiveIntensity (number): 自发光强度，0.8表示较强自发光
  //     - 其他可选参数：roughness, metalness, map等
  // 返回值：THREE.MeshStandardMaterial实例
  const sunMaterial = new THREE.MeshStandardMaterial({
    color: 0xff9900,        // 基础颜色：橙黄色
    emissive: 0xff5500,     // 自发光颜色：更亮的橙红色，模拟太阳发光
    emissiveIntensity: 0.8, // 自发光强度：0.8 (0-1之间)
  });
  // 创建网格对象
  // THREE.Mesh() - 创建网格对象，组合几何体和材质
  // 作用：将几何形状和材质结合，创建可渲染的太阳物体
  // 参数：
  //   - geometry (Geometry): 几何体对象，这里为太阳几何体
  //   - material (Material): 材质对象，这里为太阳材质
  // 返回值：THREE.Mesh实例
  sun = new THREE.Mesh(sunGeometry, sunMaterial);
  // 将太阳添加到场景
  // scene.add() - 将对象添加到场景中
  // 作用：将太阳网格对象添加到场景中进行渲染
  // 参数：
  //   - object (Object3D): 要添加的对象，这里为太阳网格
  // 返回值：无
  scene.add(sun);

  // 创建地球
  // 创建球体几何体
  // THREE.SphereGeometry() - 创建球体几何体
  // 作用：定义地球的3D形状，比太阳小
  // 参数：
  //   - radius (number): 球体半径，0.5单位
  //   - widthSegments (number): 宽度分段数，32
  //   - heightSegments (number): 高度分段数，32
  // 返回值：THREE.SphereGeometry实例
  const earthGeometry = new THREE.SphereGeometry(0.5, 32, 32);
  // 创建标准材质
  // THREE.MeshStandardMaterial() - 创建基于物理渲染的标准材质
  // 作用：定义地球表面的外观特性，蓝色模拟海洋和大气
  // 参数：
  //   - options (object): 材质配置选项
  //     - color (number): 基础颜色，十六进制值(0x2233ff)表示蓝色
  //     - roughness (number): 粗糙度，0.8表示表面不太光滑
  //     - metalness (number): 金属度，0.2表示轻微金属感
  // 返回值：THREE.MeshStandardMaterial实例
  const earthMaterial = new THREE.MeshStandardMaterial({
    color: 0x2233ff,    // 蓝色
    roughness: 0.8,     // 粗糙度：0.8 (表面不太光滑)
    metalness: 0.2,     // 金属度：0.2 (轻微金属感)
  });
  // 创建网格对象
  // THREE.Mesh() - 创建网格对象，组合几何体和材质
  // 作用：将几何形状和材质结合，创建可渲染的地球物体
  // 参数：
  //   - geometry (Geometry): 几何体对象，这里为地球几何体
  //   - material (Material): 材质对象，这里为地球材质
  // 返回值：THREE.Mesh实例
  earth = new THREE.Mesh(earthGeometry, earthMaterial);
  // 设置地球位置
  // earth.position.set() - 设置地球在3D空间中的位置
  // 作用：确定地球相对于太阳的位置，这里设置在X轴上距离5单位
  // 参数：
  //   - x (number): X轴坐标，5表示在太阳右侧5单位
  //   - y (number): Y轴坐标，0表示在同一水平面
  //   - z (number): Z轴坐标，0表示在同一深度
  // 返回值：无
  earth.position.set(5, 0, 0);

  // 创建地球轨道（可视化）
  // 创建圆环几何体
  // THREE.RingGeometry() - 创建圆环几何体
  // 作用：定义地球轨道的3D形状，圆环用于可视化轨道
  // 参数：
  //   - innerRadius (number): 内半径，4.8单位
  //   - outerRadius (number): 外半径，5.2单位
  //   - thetaSegments (number): 分段数，64表示圆环较平滑
  //   - phiSegments (number, 可选): 径向分段数，默认1
  //   - thetaStart (number, 可选): 起始角度，默认0
  //   - thetaLength (number, 可选): 角度范围，默认2π
  // 返回值：THREE.RingGeometry实例
  const earthOrbitGeometry = new THREE.RingGeometry(4.8, 5.2, 64);
  // 创建基础材质
  // THREE.MeshBasicMaterial() - 创建基础材质
  // 作用：定义轨道外观，不受光照影响，半透明白色
  // 参数：
  //   - options (object): 材质配置选项
  //     - color (number): 颜色，十六进制值(0xffffff)表示白色
  //     - side (number): 渲染面，THREE.DoubleSide表示双面渲染
  //     - transparent (boolean): 是否透明，true开启透明度
  //     - opacity (number): 透明度值，0.3表示70%透明
  // 返回值：THREE.MeshBasicMaterial实例
  const earthOrbitMaterial = new THREE.MeshBasicMaterial({
    color: 0xffffff,        // 白色
    side: THREE.DoubleSide, // 双面渲染（从两面都能看到）
    transparent: true,      // 开启透明度
    opacity: 0.3,           // 透明度：0.3 (70%透明)
  });
  // 创建网格对象
  // THREE.Mesh() - 创建网格对象，组合几何体和材质
  // 作用：将几何形状和材质结合，创建可渲染的轨道物体
  // 参数：
  //   - geometry (Geometry): 几何体对象，这里为轨道几何体
  //   - material (Material): 材质对象，这里为轨道材质
  // 返回值：THREE.Mesh实例
  earthOrbit = new THREE.Mesh(earthOrbitGeometry, earthOrbitMaterial);
  // 旋转轨道
  // earthOrbit.rotation.x - 设置轨道绕X轴的旋转
  // 作用：调整轨道方向，使其在X-Z平面上（水平面）
  // 参数：
  //   - 直接赋值：rotation.x = Math.PI / 2 表示绕X轴旋转90度
  // 返回值：无
  earthOrbit.rotation.x = Math.PI / 2;
  // 将轨道添加到场景
  // scene.add() - 将对象添加到场景中
  // 作用：将轨道网格对象添加到场景中进行渲染
  // 参数：
  //   - object (Object3D): 要添加的对象，这里为轨道网格
  // 返回值：无
  scene.add(earthOrbit);

  // 创建月球
  // 创建球体几何体
  // THREE.SphereGeometry() - 创建球体几何体
  // 作用：定义月球的3D形状，比地球小
  // 参数：
  //   - radius (number): 球体半径，0.2单位
  //   - widthSegments (number): 宽度分段数，32
  //   - heightSegments (number): 高度分段数，32
  // 返回值：THREE.SphereGeometry实例
  const moonGeometry = new THREE.SphereGeometry(0.2, 32, 32);
  // 创建标准材质
  // THREE.MeshStandardMaterial() - 创建基于物理渲染的标准材质
  // 作用：定义月球表面的外观特性，灰色模拟月球表面
  // 参数：
  //   - options (object): 材质配置选项
  //     - color (number): 基础颜色，十六进制值(0xaaaaaa)表示灰色
  //     - roughness (number): 粗糙度，0.9表示表面很粗糙
  //     - metalness (number): 金属度，0.1表示低金属度
  // 返回值：THREE.MeshStandardMaterial实例
  const moonMaterial = new THREE.MeshStandardMaterial({
    color: 0xaaaaaa,    // 灰色
    roughness: 0.9,     // 高粗糙度（月球表面粗糙）
    metalness: 0.1,     // 低金属度
  });
  // 创建网格对象
  // THREE.Mesh() - 创建网格对象，组合几何体和材质
  // 作用：将几何形状和材质结合，创建可渲染的月球物体
  // 参数：
  //   - geometry (Geometry): 几何体对象，这里为月球几何体
  //   - material (Material): 材质对象，这里为月球材质
  // 返回值：THREE.Mesh实例
  moon = new THREE.Mesh(moonGeometry, moonMaterial);
  // 设置月球位置
  // moon.position.set() - 设置月球在3D空间中的位置
  // 作用：确定月球相对于地球的位置，这里设置在X轴上距离1.5单位
  // 参数：
  //   - x (number): X轴坐标，1.5表示在地球右侧1.5单位
  //   - y (number): Y轴坐标，0表示在同一水平面
  //   - z (number): Z轴坐标，0表示在同一深度
  // 返回值：无
  moon.position.set(1.5, 0, 0);

  // 将月球添加为地球的子对象
  // 将月球添加为地球的子对象
  // earth.add() - 将对象添加为子对象
  // 作用：将月球网格对象添加为地球的子对象，继承地球的变换（随地球一起运动）
  // 参数：
  //   - object (Object3D): 要添加的对象，这里为月球网格
  // 返回值：无
  earth.add(moon);

  // 将地球添加到场景
  // scene.add() - 将对象添加到场景中
  // 作用：将地球网格对象添加到场景中进行渲染
  // 参数：
  //   - object (Object3D): 要添加的对象，这里为地球网格
  // 返回值：无
  scene.add(earth);

  // 创建月球轨道（可视化）
  // 创建圆环几何体
  // THREE.RingGeometry() - 创建圆环几何体
  // 作用：定义月球轨道的3D形状，圆环用于可视化轨道
  // 参数：
  //   - innerRadius (number): 内半径，1.3单位
  //   - outerRadius (number): 外半径，1.7单位
  //   - thetaSegments (number): 分段数，32表示圆环较平滑
  // 返回值：THREE.RingGeometry实例
  const moonOrbitGeometry = new THREE.RingGeometry(1.3, 1.7, 32);
  // 创建基础材质
  // THREE.MeshBasicMaterial() - 创建基础材质
  // 作用：定义轨道外观，不受光照影响，浅灰色更透明
  // 参数：
  //   - options (object): 材质配置选项
  //     - color (number): 颜色，十六进制值(0xcccccc)表示浅灰色
  //     - side (number): 渲染面，THREE.DoubleSide表示双面渲染
  //     - transparent (boolean): 是否透明，true开启透明度
  //     - opacity (number): 透明度值，0.2表示80%透明
  // 返回值：THREE.MeshBasicMaterial实例
  const moonOrbitMaterial = new THREE.MeshBasicMaterial({
    color: 0xcccccc,        // 浅灰色
    side: THREE.DoubleSide, // 双面渲染
    transparent: true,      // 开启透明度
    opacity: 0.2,           // 透明度：0.2 (80%透明)
  });
  // 创建网格对象
  // THREE.Mesh() - 创建网格对象，组合几何体和材质
  // 作用：将几何形状和材质结合，创建可渲染的轨道物体
  // 参数：
  //   - geometry (Geometry): 几何体对象，这里为轨道几何体
  //   - material (Material): 材质对象，这里为轨道材质
  // 返回值：THREE.Mesh实例
  moonOrbit = new THREE.Mesh(moonOrbitGeometry, moonOrbitMaterial);
  // 旋转轨道
  // moonOrbit.rotation.x - 设置轨道绕X轴的旋转
  // 作用：调整轨道方向，使其在X-Z平面上（水平面）
  // 参数：
  //   - 直接赋值：rotation.x = Math.PI / 2 表示绕X轴旋转90度
  // 返回值：无
  moonOrbit.rotation.x = Math.PI / 2;
  // 将轨道添加为地球的子对象
  // earth.add() - 将对象添加为子对象
  // 作用：将轨道网格对象添加为地球的子对象，继承地球的变换（随地球一起移动）
  // 参数：
  //   - object (Object3D): 要添加的对象，这里为轨道网格
  // 返回值：无
  earth.add(moonOrbit);

  // 设置相机位置
  // camera.position.set() - 设置相机在3D空间中的位置
  // 作用：确定相机的观察位置，从上方和侧方观察整个太阳系
  // 参数：
  //   - x (number): X轴坐标，0表示在中心
  //   - y (number): Y轴坐标，15表示在上方
  //   - z (number): Z轴坐标，15表示在侧后方
  // 返回值：无
  camera.position.set(0, 15, 15);
  // 设置相机看向点
  // camera.lookAt() - 设置相机注视的目标点
  // 作用：让相机朝向指定的3D坐标点，这里看向场景中心（太阳位置）
  // 参数：
  //   - x (number): X轴坐标，0表示场景中心
  //   - y (number): Y轴坐标，0表示场景中心
  //   - z (number): Z轴坐标，0表示场景中心
  // 或者使用 Vector3 对象
  // 返回值：无
  camera.lookAt(0, 0, 0);
};

// 动画循环函数
const animate = (): void => {
  // 请求下一帧动画，形成循环
  // 请求动画帧
  // requestAnimationFrame() - 浏览器API，请求下一帧动画
  // 作用：在浏览器下次重绘前调用指定的回调函数，形成平滑的动画循环
  // 参数：
  //   - callback (function): 回调函数，这里为animate函数
  // 返回值：number - 请求ID，用于取消动画
  animationId = requestAnimationFrame(animate);

  // 旋转地球（自转）
  // earth.rotation.y += 0.005 - 修改地球绕Y轴的旋转
  // 作用：每帧将地球绕Y轴旋转0.005弧度，创造地球自转效果
  // 参数：
  //   - 直接操作：rotation.y += 0.005 表示Y轴旋转增加0.005弧度
  // 返回值：无
  earth.rotation.y += 0.005; // 地球自转：每帧绕y轴旋转0.005弧度
  
  // 使用时间计算地球在轨道上的位置
  // Date.now() * 0.001 将毫秒转换为秒，使动画与时间相关而非帧率相关
  const time = Date.now() * 0.001;
  // 使用三角函数计算地球在圆形轨道上的x和z坐标
  // Math.cos 和 Math.sin 创建圆周运动，*5 是轨道半径
  // 设置地球位置（公转）
  // earth.position.x/z - 设置地球在X和Z轴的位置
  // 作用：使用三角函数计算地球在圆形轨道上的位置，模拟公转
  // 参数：
  //   - Math.cos(time * 0.5) * 5: 计算X坐标，基于时间和半径5
  //   - Math.sin(time * 0.5) * 5: 计算Z坐标，基于时间和半径5
  // 返回值：无
  earth.position.x = Math.cos(time * 0.5) * 5;  // x坐标随时间变化
  earth.position.z = Math.sin(time * 0.5) * 5;  // z坐标随时间变化

  // 旋转月球（自转）
  // moon.rotation.y += 0.01 - 修改月球绕Y轴的旋转
  // 作用：每帧将月球绕Y轴旋转0.01弧度，创造月球自转效果，比地球快
  // 参数：
  //   - 直接操作：rotation.y += 0.01 表示Y轴旋转增加0.01弧度
  // 返回值：无
  moon.rotation.y += 0.01; // 月球自转：每帧绕y轴旋转0.01弧度（比地球快）
  
  // 使用不同的时间计算月球在轨道上的位置
  const moonTime = Date.now() * 0.002;  // 时间乘数更大，月球运动更快
  // 计算月球相对于地球的位置（圆形轨道）
  // 注意：月球是地球的子对象，所以这个位置是相对于地球的局部坐标
  // 设置月球位置（公转）
  // moon.position.x/z - 设置月球在X和Z轴的位置
  // 作用：使用三角函数计算月球在圆形轨道上的位置，模拟公转
  // 参数：
  //   - Math.cos(moonTime) * 1.5: 计算X坐标，基于时间和半径1.5
  //   - Math.sin(moonTime) * 1.5: 计算Z坐标，基于时间和半径1.5
  // 返回值：无
  moon.position.x = Math.cos(moonTime) * 1.5;  // x坐标随时间变化
  moon.position.z = Math.sin(moonTime) * 1.5;  // z坐标随时间变化

  // 渲染场景
  // renderer.render() - 渲染3D场景
  // 作用：将场景中的对象通过相机视角渲染到canvas中，显示最终图像
  // 参数：
  //   - scene (Scene): 要渲染的场景对象
  //   - camera (Camera): 用于渲染的相机对象
  // 返回值：无
  renderer.render(scene, camera);
};

// 窗口大小改变处理函数
const handleResize = (): void => {
  // 检查相机和渲染器是否已初始化
  if (!camera || !renderer) {return;}
  // 更新相机宽高比
  // camera.aspect - 设置相机的宽高比属性
  // 作用：根据窗口尺寸调整相机宽高比，防止图像拉伸变形
  // 参数：
  //   - 直接赋值：aspect = window.innerWidth / window.innerHeight 计算新的宽高比
  // 返回值：无
  camera.aspect = window.innerWidth / window.innerHeight;
  // 更新相机投影矩阵
  // camera.updateProjectionMatrix() - 更新相机的投影矩阵
  // 作用：当相机参数（如宽高比）改变后，必须调用此方法重新计算投影矩阵
  // 参数：无
  // 返回值：无
  camera.updateProjectionMatrix();
  // 更新渲染器大小
  // renderer.setSize() - 设置渲染器的输出canvas大小
  // 作用：当窗口尺寸改变时，调整渲染器绘制区域的大小
  // 参数：
  //   - width (number): 宽度像素值，使用窗口内宽
  //   - height (number): 高度像素值，使用窗口内高
  // 返回值：无
  renderer.setSize(window.innerWidth, window.innerHeight);
};

// Vue组件挂载生命周期钩子
// 当组件被挂载到DOM时执行
onMounted(() => {
  initThreeJS();  // 初始化Three.js场景
  animate();      // 开始动画循环
  // 添加窗口大小改变事件监听器
  window.addEventListener('resize', handleResize);
});

// Vue组件卸载生命周期钩子
// 当组件从DOM中移除时执行（清理工作）
onUnmounted(() => {
  // 移除窗口大小改变事件监听器
  window.removeEventListener('resize', handleResize);
  // 取消动画帧
  // cancelAnimationFrame() - 浏览器API，取消动画帧请求
  // 作用：停止动画循环，释放资源
  // 参数：
  //   - animationId (number): 之前requestAnimationFrame返回的ID
  // 返回值：无
  if (animationId) {
    cancelAnimationFrame(animationId);
  }
  // 清理Three.js资源
  if (renderer && container.value) {
    // 从DOM移除canvas元素
    // container.value.removeChild() - DOM操作方法
    // 作用：将Three.js渲染器的canvas元素从页面中移除
    // 参数：
    //   - renderer.domElement: 渲染器的canvas DOM元素
    // 返回值：无
    container.value.removeChild(renderer.domElement);
    // 释放渲染器资源
    // renderer.dispose() - 释放渲染器占用的资源
    // 作用：清理WebGL上下文、着色器程序等，防止内存泄漏
    // 参数：无
    // 返回值：无
    renderer.dispose();
  }
});
</script>

<style scoped>
/* 样式部分：设置容器样式 */
.solar-system-container {
  width: 100%;        /* 宽度100%填充父容器 */
  height: 100vh;      /* 高度100%视口高度 */
  margin: 0;          /* 外边距为0 */
  padding: 0;         /* 内边距为0 */
  overflow: hidden;   /* 隐藏溢出内容 */
  background-color: #000; /* 黑色背景，模拟太空 */
}
</style>